package com.hongdee.rbac.res.service.impl;


import com.hongdee.common.Constant;
import com.hongdee.common.util.TokenUtil;
import com.hongdee.rbac.res.dao.ITBcResourceDao;
import com.hongdee.rbac.res.entity.TBcResource;
import com.hongdee.rbac.res.service.ITBcResourceService;
import com.hongdee.rbac.role.entity.TBcRoleResource;
import com.mysql.jdbc.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by My on 2017-01-11.
 */
@Service
public class TBcResourceServiceImpl implements ITBcResourceService {

    private String tabName = "T_BC_RESOURCE";

    //当前用户分配的资源
    private Map<String, String> userResMap;

    @Autowired
    private ITBcResourceDao tBcResourceDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 方法名称: info
     * 方法描述: 根据 ID 查询实体详情
     * 参数名称: String id
     * 返回内容: TBcResource 实例
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */

    @Override
    public Map info(String id) throws Exception {
        if (org.springframework.util.StringUtils.isEmpty(id)) {
            throw new Exception("请选择资源");
        }
        String sql = "select * from " + tabName + " where id = ? ";
        return this.tBcResourceDao.info(sql, id);
    }


    /**
     * 方法名称: save
     * 方法描述: 将 JSON 字符串转换为实体保存在数据库中
     * 参数名称: String data
     * 返回内容: 保存后的实体对象
     * 异常说明: Exception
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     *
     * @param data
     */
    @Override
    public TBcResource save(TBcResource data) throws Exception {

        if (null == data.getId() || StringUtils.isNullOrEmpty(data.getId())) {
            this.tBcResourceDao.saveOrUpdate(data);
            //保存关联关系
            TBcRoleResource tr = new TBcRoleResource();
            tr.setResId(data.getId());
            tr.setrId(Constant.SUPER_ADMIN_RID);
            this.tBcResourceDao.saveOrUpdate(tr);
        } else {
            //编辑
            this.tBcResourceDao.saveOrUpdate(data);
        }
        return data;
    }

    /**
     * 方法名称: del
     * 方法描述: 查询下级资源
     * 参数名称: String ids
     * 返回内容:
     * 异常说明: Exception
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */

    @Override
    public void update(String id, String status) throws Exception {

        if (StringUtils.isNullOrEmpty(id)) {
            throw new Exception("请选择记录！");
        }
        String hql = "update TBcResource t set t.resStatus =:status  where t.id = :id ";
        System.out.print(id);
        Map params = new HashMap();
        params.put("id", id);
        params.put("status", status);
        this.tBcResourceDao.update(hql, params);


    }

    /**
     * 方法名称: child
     * 方法描述: 查询下级资源
     * 参数名称: String uid
     * 参数名称: String token
     * 返回内容: List<Map<String,Object> 资源实体转 Map 后的集合
     * 异常说明: Exception
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    public List<Map<String, Object>> child(String node) throws Exception {
        //此处做权限较验
        //现阶段直接返回
        if (org.springframework.util.StringUtils.isEmpty(node) || "root".equals(node)) {
            node = "0";
        }
        String sqlStr = "select p.id,p.res_name,p.res_path,p.res_ico,p.res_order,p.res_p_id,count(c.id) as childcount"
                + " from t_bc_resource p left join  t_bc_resource c on p.id = c.res_p_id where p.res_status='1' "
                + " and p.res_p_id = ? group by p.id,p.res_name,p.res_ico   order by p.res_order";
        //绑定占位符
        Object[] params = new Object[]{node};
        return this.tBcResourceDao.list(sqlStr, params);
    }

    /**
     * 方法名称:menu
     * 方法描述: 查询当前资源所有的子资源
     * 参数名称: a
     * 参数名称: b
     * 返回内容:所有子资源集合
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     *
     * @param node
     * @param id
     */
    @Override
    public List menu(String node, String id) throws Exception {

        //node有值时，根据 Node 查询
        //否则根据 id 查询
        String pId = node;
        if (org.springframework.util.StringUtils.isEmpty(node) || "root".equals(node)) {
            pId = id;
        }
        String sqlStrs = " select p.id,p.res_name,p.res_path,p.res_ico,p.res_order,p.res_p_id,count(c.id) as childcount from t_bc_resource p "
                + "left join  t_bc_resource c on p.id = c.res_p_id where p.res_status='1'  and p.res_p_id = ?"
                + " group by p.id,p.res_name,p.res_ico  order by p.res_order";
        Object[] params = new Object[]{pId};
        return this.tBcResourceDao.list(sqlStrs, params);
    }

    /**
     * 方法名称: BuildTreeChild
     * 方法描述: 查询左侧资源树，同步一次性加载
     * 参数名称: resId 子系统 ID
     * 返回内容: 无
     * 异常说明: 抛出异常Exception
     * 创建用户: MissJin
     * 创建时间: 2017/1/21/16:28
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public List tree(String resId) throws Exception {
        if (StringUtils.isNullOrEmpty(resId)) {
            resId = "0";
        }
        String sqlStr = "select * from t_bc_resource where res_p_id = ? order by res_order asc";
        Object[] params = new Object[]{resId};
        List<Map<String, Object>> treeP = this.tBcResourceDao.list(sqlStr, params);
        return buildTreeParent(treeP);
    }

    /**
     * 方法名称: BuildTreeParent
     * 方法描述: 获取当前节点的子节点，并生成树状结点，结合BuildTreeChild使用
     * 参数名称: List<Map<String, Object>> treeP 树节点集合
     * 返回内容: 无
     * 异常说明: 抛出异常Exception
     * 创建用户: MissJin
     * 创建时间: 2017/1/21/16:11
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    private List buildTreeParent(List<Map<String, Object>> treeP) throws Exception {

        if (treeP.size() == 0) {
            return treeP;
        }

        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id"));
            List<Map<String, Object>> childList = tree(resId);
            map.put("child", childList);
        }
        return treeP;
    }

    /**
     * 方法名称: findTreeChild
     * 方法描述: 根据资源 ID 查询下级菜单
     * 参数名称: string id 资源ID
     * 返回内容:
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public List findTreeChild(String id) throws Exception {
        if (StringUtils.isNullOrEmpty(id)) {
            id = "0";
        }
        String sqlStr = "select * from t_bc_resource where res_p_id = ? order by res_order asc";
        Object[] params = new Object[]{id};
        return this.tBcResourceDao.list(sqlStr, params);
    }

    /**
     * 查询用户有权限分配的资源树
     *
     * @param id
     * @return
     */
    @Override
    public List userResTree(String id, String uid) throws Exception {
        userResMap = TokenUtil.getRes(uid);
        return userResTreeChild(id);
    }

    /**
     * 构建树型结构子数据列表
     *
     * @param pid
     * @return
     * @throws Exception
     */
    private List userResTreeChild(String pid) throws Exception {
        if (StringUtils.isNullOrEmpty(pid)) {
            pid = "0";
        }
        String sqlStr = "select * from t_bc_resource where res_p_id = ? and res_status='1' order by res_order asc";
        Object[] params = new Object[]{pid};
        List<Map<String, Object>> treeP = this.tBcResourceDao.list(sqlStr, params);
        return userResTreeParent(treeP);
    }

    /**
     * 拼接树型结构父节点
     *
     * @param treeP
     * @return
     * @throws Exception
     */
    private List userResTreeParent(List<Map<String, Object>> treeP) throws Exception {

        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> treeList = new ArrayList<>();
        List<Map<String, Object>> childList;
        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id"));
            childList = userResTreeChild(resId);
            if (childList.size() == 0) {
                //不存在子节点时，判断当前节点是为选中节点
                if (userResMap.containsKey(resId)) {
                    System.out.println(map.get("resName"));
                    treeList.add(map);
                }

            } else {
                //存在子节点，增加子节点 返回
                map.put("child", childList);
                treeList.add(map);
            }
        }
        return treeList;
    }


}
